package org.eclipse.moquette.spi.impl;

import org.eclipse.moquette.proto.messages.AbstractMessage;
import org.eclipse.moquette.server.ServerChannel;

import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;

/**
 * Created by alex on 15-6-5.
 */
public class AnnotationSupport {

    private final Map<Class, Method> messageClassToMethod = new HashMap<>();
    private Object targetInstance;

    /**
     * 通过反射找到 指定实例里面 使用@MQTTMessage注解的方法
     * @param instance
     */
    void processAnnotations(Object instance) {
        targetInstance = instance;
        Class instanceCls = instance.getClass();
        Method[] allMethods = instanceCls.getDeclaredMethods();

        for (Method m : allMethods) {
            MQTTMessage annotation = m.getAnnotation(MQTTMessage.class);
            if (annotation == null) {
                continue;
            }
            //找到注解上的class对象
            Class mqttMessageClass = annotation.message();
            messageClassToMethod.put(mqttMessageClass, m);
        }
    }


    void dispatch(ServerChannel session, AbstractMessage msg) {
        //通过class对象找到 处理Message的方法
        Method targetMethod = this.messageClassToMethod.get(msg.getClass());
        if (targetMethod == null) {
            throw new RuntimeException("Can't dispatch to any @MQTTMessage marked the message: " + msg);
        }
        try {
            //调用方法
            targetMethod.invoke(targetInstance, session, msg);
        } catch (Exception ex) {
            throw new RuntimeException(ex);
        }
    }
}
